;;;; To load in repl
;;;; C-c C-c on (ql:quickload "ltk")
;;;; C-c C-c on (in-package :ltk)
;;;; and any other packages.
;;;; C-c C-k from code pane, to compile in repl.
;;;; ignore warnings first time it loads.
;;;;
;;;; if db gets to be read only, close and reopen program

(Declaim (optimize (speed 0) (space 0) (debug 3) (safety 3) (compilation-speed 3)))
(ql:quickload "sqlite")
(ql:quickload "ltk")
(use-package :sqlite)
(use-package :iter)
(use-package :ltk)

(defvar *frame_listtop*  0)
(defvar *frame_listmain* 0)
(defvar *frame_listbtm*  0)
(defvar *frame_list*     0)
(defvar *frame_footer*   0)
(defvar *frame_math*     0)
(defvar *nextindex*      0)
(defvar *removeindex*    0)
(defvar *status_label*   0)
(defvar *dateforsql*     0)
(defvar *MAT_LOOP_MAT*   0) ;;these only used to insert data from templates
(defvar *MAT_LOOP_LBS*   0)
(defvar *MAT_LOOP_OZ*    0)
(defvar *MAT_LOOP_GMS*   0)
(defvar *MAT_LOOP_INT*   0)
(defvar *existing_formula* "T")
(defvar *oldtimestamp*   0)
(defvar *customerid*     0)
(defvar *load_tmp_btn* "")
(defvar *load_lot_btn* "")
(defvar *save_tmp_btn* "")
(defvar *save_lot_btn* "")

;;load lot
(defvar *lotloadwin*       "")
(defvar *customer-names*   "")
(defvar customers          "")
(defvar lotpane            "")
(defvar chosen-lot         "")
(defvar customeridnum      "")
(defvar timestampnum       "")
(defvar *select_customer*  "")
(defvar *cancel_lot*       "")
(defvar *lotlistreturn*    "")
(defvar *lotload*          "")
(defvar *timedate_convert* "")
(defvar *sqlite_row_count* "")
(defvar entrybox_year      "")
(defvar year_is            "")
(defvar year_calculate     "")
(defvar one_year_in_unixtime 31622400) ;;3600 * 24 * 366
(defvar one_month_in_unixtime 2678400) ;;3600 * 24 * 31 close enough for my needs

;;load template
(defvar *templateloadwin* "")
(defvar *country-names* "")
(defvar countries "")
(defvar content "")
(defvar chosen-item "")
(defvar dbreturn "")
(defvar *select_template*    "")
(defvar *cancel_template*    "")
(defvar *delete_template*    "")
(defvar *templatelistreturn* "")
(defvar *timedate_convert*   "")
(defvar *sqlite_row_count*   "")

;;math frame
(defvar *frame_math_main*  "")
(defvar math_label_top     "")
(defvar math_label_btm     "")
(defvar math_label_initial "")
(defvar math_label_new     "")



(defun printout ()
  ;;
  )

(defvar *name-index* 0)
(defun generate-unique-name (stem)
  (format nil "~A-~A" stem (incf *name-index*)))
(defvar *entries*
  (make-hash-table :test 'equal))
(defvar *new-name* "" )
(defvar *index* 1)
(defvar *lastentry* 0)
(defvar *nextindex* (+ 1 *index*))
(defvar *mylist* 0)
(defun get-last-entry () ;;read hash table, get last
  (loop for k being the hash-keys in *entries* using (hash-value v)
	do (setf *lastentry* k)))

;;Messages, Errors, Logging
(defun error-report (somestring numberval)
  (format t "~a Error: ~D ~&" (do-msg somestring) numberval))

(defun user-info-report (somestring numberval)
  (format t "~a Message: ~D ~&" (do-msg somestring) numberval))

;;Date without depending on external library
(defvar *unix-epoch-difference*
  (encode-universal-time 0 0 0 1 1 1970 0))

(defun universal-to-unix-time (universal-time)
  (- universal-time *unix-epoch-difference*))

(defun unix-to-universal-time (unix-time)
  (+ unix-time *unix-epoch-difference*))

(defun get-unix-time ()
  (universal-to-unix-time (get-universal-time)))

(defun get-readable-time (unixtimevalue)
  (multiple-value-bind
	;;(second minute hour day month year day-of-week dst-p tz)
	(second minute hour day month year)
      (decode-universal-time (unix-to-universal-time unixtimevalue))
    ;;(format nil "~2,'0d:~2,'0d:~2,'0d ~d/~2,'0d/~d (GMT~@d)"
    (format nil "~d/~2,'0d/~d ~2,'0d:~2,'0d:~2,'0d "
	    month
	    day
	    year
	    hour
	    minute
	    second
	    )))

;;DB related
(defvar *db* (sqlite:connect "../db_rel/recipe.db"))

;;These two try to cleanup the verbosity required for concatenating symbols from strings.
;;See docs: assign_value_to_string_returned_as_symbol

;;assign pointer to new symbol myvar
(defun symbol-in-symbol (MYVAR STR1 STR2 &optional STR3 STR4 STR5 STR6) 
  (setf MYVAR (intern (concatenate 'string STR1 STR2 STR3 STR4 STR5 STR6))))
;;pointer redirection from myvar (get what its pointing at)
(defun get-symbol-in-symbol (VAL1)
  (eval `(print ,VAL1))
  )

;; save template to sql db button / file menu ;;insertdata_templates
(load "../save_template.lisp")
;; save lot (mostly same as template) ;;insertdata_lots
(load "../save_lot.lisp")


;; start ltk loop.
(defun main ()
  (with-ltk ()

    (ltk:wm-title *tk* "Fushigi No Reshipe") ;;root must be *tk*. later windows can be different.
    (ltk:set-geometry-wh *tk* 850 600) ;;def window width 
    (setf *frame_list* (make-instance 'frame))
    (ltk:configure *frame_list* :borderwidth 2
			    :relief :raised)
    (setf *frame_listtop* (make-instance 'frame  :width 180
						 :height 10
						 :master *frame_list*))
    (setf *frame_listmain* (make-instance 'frame :width 180
						 :height 50
						 :master *frame_list*))
    (setf *frame_listbtm* (make-instance 'frame  :width 180
						 :height 10
						 :master *frame_list*))
    (setf *frame_math* (make-instance 'frame     :width 30
						 :height 10))
    (setf *frame_footer* (make-instance 'frame))

    (ltk:configure *frame_math*  :borderwidth 2
	          	     :relief :raised)
    
    (ltk:configure *frame_listmain* :borderwidth 2
				:relief :raised)

    ;; load widgets for bottom part of main page (list of materials)
    (load "../entrys.lisp") ;;can't get loop to work. Manually enter.

    ;; load widgets for top part of main page
    (load "../frametop_list.lisp") ;; lot#, date, etc...
    
    ;;root window
    (ltk:grid *frame_list* 0 0     :padx 35
			       :pady 35
			       :sticky "wns")
    (ltk:grid *frame_math* 0 1     :padx 10
	                       :pady 35
			       :sticky "wn ")
    ;;child frames of frame_list
    (ltk:grid *frame_listtop* 1 0  :pady 1
			       :sticky "new"
			       :columnspan "2")
    (ltk:grid *frame_listmain* 2 0 :pady 1
			       :sticky "new"
			       :columnspan "2")
    (ltk:grid *frame_listbtm* 3 0  :pady 1
			       :sticky "new"
			       :columnspan "2")
    (ltk:grid *frame_footer* 1 0   :padx 50
			       :pady 5
			       :sticky "we") ;; parent frame must stretch east and west
    (setf *status_label* (make-instance 'label :master *frame_footer*
					       :text "default" :anchor "w"))
    (ltk:grid *status_label* 0 0 :sticky "sw") ;; for this child to be on the far right.

    ;; notifications on bottom right of main window
    (load "../status_label_bindings.lisp")
    

    (setf *load_tmp_btn* (make-instance 'button :text "Load Template"
						:command #'(lambda () (loadtemplatedialog))
						:master *frame_listbtm*))
    (setf *save_tmp_btn* (make-instance 'button :text "Save Template"
						:command #'(lambda () (insertdata_templates))
						:master *frame_listbtm*))
    (setf *load_lot_btn* (make-instance 'button :text "Load Lot"
						:command #'(lambda () (loadlotdialog))
						:master *frame_listbtm*))
    (setf *save_lot_btn* (make-instance 'button :text "Save Lot"
						:command #'(lambda () (insertdata_lots))
						:master *frame_listbtm*))
    (ltk:grid *load_tmp_btn*  2 0 :sticky "s"
			      :pady 3)
    (ltk:grid *save_tmp_btn*  2 1 :sticky "s"
			      :pady 3)
    (ltk:grid *load_lot_btn*  2 3 :sticky "s"
  			      :pady 3)
    (ltk:grid *save_lot_btn*  2 4 :sticky "s"
			      :pady 3)

    
    (load "../clear_all.lisp")
    (defvar *clear_all_btn* "")
    (setf *clear_all_btn* (make-instance 'button :text "Clear All"
						 :command #'(lambda () (clear_all))
						 :master *frame_listbtm*))
    (ltk:grid *clear_all_btn*  1 0 :sticky "s"
			       :pady 3)
    
    ;; need weight and sticky to have it resize properly
    ;; and also must have *tk* / root window with weight of 1
    (ltk:grid-columnconfigure *tk* 0 :weight 1 )
    (ltk:grid-columnconfigure *tk* 1 :weight 10 )                       
    (ltk:grid-rowconfigure *tk* 0 :weight 100)
    (ltk:grid-rowconfigure *tk* 1 :weight 1)
    
    (ltk:grid-columnconfigure *frame_list* 0 :weight 1)
    (ltk:grid-columnconfigure *frame_list* 1 :weight 1)
    (ltk:grid-columnconfigure *frame_list* 2 :weight 2)
    (ltk:grid-columnconfigure *frame_list* 3 :weight 30)
    (ltk:grid-columnconfigure *frame_list* 4 :weight 2)
    (ltk:grid-columnconfigure *frame_list* 5 :weight 1)
    (ltk:grid-rowconfigure    *frame_list* 0 :weight 1)
    (ltk:grid-rowconfigure    *frame_list* 1 :weight 1);;watch the weights!
    (ltk:grid-rowconfigure    *frame_list* 2 :weight 30)
    (ltk:grid-rowconfigure    *frame_list* 3 :weight 1)
    
    (ltk:grid-columnconfigure *frame_listtop* 0 :weight 15)
    (ltk:grid-columnconfigure *frame_listtop* 1 :weight 10)
    (ltk:grid-columnconfigure *frame_listtop* 2 :weight 20)
    (ltk:grid-columnconfigure *frame_listtop* 3 :weight 5)
    (ltk:grid-columnconfigure *frame_listtop* 4 :weight 20)
    (ltk:grid-rowconfigure    *frame_listtop* 0 :weight 1)
    (ltk:grid-rowconfigure    *frame_listtop* 1 :weight 1)
    (ltk:grid-rowconfigure    *frame_listtop* 2 :weight 1)
    (ltk:grid-rowconfigure    *frame_listtop* 3 :weight 1)
    (ltk:grid-rowconfigure    *frame_listtop* 4 :weight 1)
    (ltk:grid-rowconfigure    *frame_listtop* 5 :weight 5)
    (ltk:grid-rowconfigure    *frame_listtop* 6 :weight 1)

    (ltk:grid-columnconfigure *frame_listbtm* 0 :weight 10)
    (ltk:grid-columnconfigure *frame_listbtm* 1 :weight 10)
    (ltk:grid-columnconfigure *frame_listbtm* 2 :weight 10)
    (ltk:grid-columnconfigure *frame_listbtm* 3 :weight 10)
    (ltk:grid-columnconfigure *frame_listbtm* 4 :weight 10)
    
    (ltk:grid-columnconfigure *frame_listmain* 0 :weight 1)
    (ltk:grid-columnconfigure *frame_listmain* 1 :weight 1)
    (ltk:grid-rowconfigure    *frame_listmain* 0 :weight 1)
    (ltk:grid-rowconfigure    *frame_listmain* 1 :weight 1)

    (ltk:grid-columnconfigure *frame_footer* 0 :weight 1)
    (ltk:grid-rowconfigure    *frame_footer* 0 :weight 1)

    (ltk:font-configure "TkTextFont" :size 8) ;;in the actual entry box (not label)
    (ltk:font-configure "TkDefaultFont" :size 8 ) ;;labels of things.
    (ltk:font-configure "TkFixedFont" :size 8 ) ;;the large textbox uses this
    (ltk:font-configure "TkMenuFont" :size 8 ) ;;menubar
    
    ;; file, edit menu
    (load "../menubar.lisp")

    ;; listbox (window) for load template button
    (load "../load_template.lisp")

    ;; listbox (window) for load lot button
    (load "../load_lot.lisp")
    
    ;; convert gallons to drums
    (load "../math_frame.lisp")

    )
  )
(main) ;;must actually run main...

;;(bind *tk* "<Return>" #'(lambda (evt) (printout)))

;; rows, columns
